package com.logica.tutorial.web;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormValidatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.SimpleFormComponentLabel;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import com.logica.tutorial.dto.PersonDTO;
import com.logica.tutorial.model.Parent;
import com.logica.tutorial.model.Person;
import com.logica.tutorial.model.Sex;
import com.logica.tutorial.service.PersonService;

public class SelectPersonPanel extends Panel {
	private Person person;

	@SpringBean
	private PersonService personService;
	private FormComponent<?> parentField;
	private Parent fieldToFill;
	private LoadableDetachableModel personList;
	private WebMarkupContainer listContainer;
	private Sex parentSex = Sex.NA;

	public void setParentField(FormComponent<?> parentField) {
		this.parentField = parentField;
	}

	public void hideResultList() {
		listContainer.setVisible(false);
	}
	
	public void showResultList() {
		listContainer.setVisible(true);
	}
	
	public SelectPersonPanel(String id, final HomePage homePage,
			final ModalWindow modal) {
		super(id);

		person = new Person();
		// get the list of items to display from provider (database, etc)
		// in the form of a LoadableDetachableModel
		personList = new LoadableDetachableModel() {
			protected Object load() {
				return personService.findPerson(person);
			}
		};

		@SuppressWarnings("unchecked")
		final ListView personLinkView = new ListView("personList", personList) {
			@Override
			protected void populateItem(ListItem item) {
				final PersonDTO personItem = (PersonDTO) item.getModelObject();
				AjaxLink link = new AjaxLink("personLink") {
					public void onClick(AjaxRequestTarget target) {
						Person parent = new Person();
						parent.setId(personItem.getId());
						parent.setFirstName(personItem.getFirstName());
						parent.setLastName(personItem.getLastName());
						homePage.setParent(parent);

						parentField.setDefaultModelObject(parent);
						target.add(parentField);
						person = new Person();
						hideResultList();
						modal.close(target);
					}
				};
				link.setOutputMarkupId(true);
				link.add(new Label("personLinkText", personItem.getId() + ", "
						+ personItem.getLastName() + ", "
						+ personItem.getFirstName()));
				item.add(link);
			}
		};
		
		// encapsulate the ListView in a WebMarkupContainer in order for it to
		// update
		listContainer = new WebMarkupContainer("listContainer");
		// generate a markup-id so the contents can be updated through an AJAX
		// call
		listContainer.setOutputMarkupId(true);
		hideResultList();
		listContainer.setOutputMarkupPlaceholderTag(true);
		listContainer.add(personLinkView);
		add(listContainer);

		CompoundPropertyModel personModel = new CompoundPropertyModel(person);

		Form<Person> form = new Form<Person>("selectForm", personModel);
		form.setOutputMarkupId(true);
		add(form);

		final FeedbackPanel feedback = new FeedbackPanel("feedback");
		feedback.setOutputMarkupId(true);
		add(feedback);

		FormComponent<?> fc;
		// add form components to the form as usual

		fc = new TextField<Long>("id");
		fc.setLabel(new ResourceModel("label.Id"));
		fc.setOutputMarkupId(true);
		form.add(fc);
		form.add(new SimpleFormComponentLabel("id-label", fc));

		fc = new TextField<String>("firstName")
				.setConvertEmptyInputStringToNull(false);
		fc.setLabel(new ResourceModel("label.firstName"));
		form.add(fc);
		form.add(new SimpleFormComponentLabel("firstName-label", fc));

		fc = new TextField<String>("lastName")
				.setConvertEmptyInputStringToNull(false);
		fc.setLabel(new ResourceModel("label.lastName"));
		form.add(fc);
		form.add(new SimpleFormComponentLabel("lastName-label", fc));

		form.add(new AjaxButton("search-ajax-button", form) {

			@Override
			protected void onSubmit(AjaxRequestTarget target, Form form) {
				person = (Person) form.getDefaultModelObject();
				if (parentSex == Sex.MALE)
					person.setSex(Sex.MALE);
				if (parentSex == Sex.FEMALE)
					person.setSex(Sex.FEMALE);
				
				target.add(listContainer);
				showResultList();
				form.clearInput();
			}

			@Override
			protected void onError(AjaxRequestTarget target, Form<?> form) {
				// repaint the feedback panel so errors are shown
				target.add(feedback);
			}
		});

		AjaxFormValidatingBehavior.addToAllFormComponents(form, "onsubmit");
	}

	public void setParentSex(Sex sex) {
		parentSex = sex;
	}
}
